package com.ebt.m.proposal_v2.widget.view;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;

import com.ebt.m.R;
import com.ebt.m.proposal_v2.widget.base.RadioView;

/**
 * 一个用于实现单选的ViewGroup,可以自由进行水平、垂直排列；可以添加任意子View,但是子View必须继承RadioView
 *
 * @author archer.qi
 *         Created on 2017/5/5.
 */
public class RadioBox extends LinearLayout {

    private int spaceHorizontal;
    private int spaceVertical;

    private OnCheckChangedListener onCheckChangedListener;

    public RadioBox(Context context) {
        this(context, null);
    }

    public RadioBox(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.RadioBox);
        spaceHorizontal = (int) t.getDimension(R.styleable.RadioBox_spaceHorizontal, 10);
        spaceVertical = (int) t.getDimension(R.styleable.RadioBox_spaceVertical, 10);
        super.setOnHierarchyChangeListener(new CheckHierarchyChangeListener());
    }

    public void setOnCheckChangedListener(OnCheckChangedListener listener) {
        this.onCheckChangedListener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View childView = getChildAt(i);
            if (childView != null) {
                measureChild(childView, widthMeasureSpec, heightMeasureSpec);
            }
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        if (changed) {
            if (getOrientation() == HORIZONTAL) {
                layoutHorizontal(l, t, r, b);
            }
            if (getOrientation() == VERTICAL) {
                layoutVertical(l, t, r, b);
            }
        }
    }

    private void layoutHorizontal(int l, int t, int r, int b) {
        final int left = l + getPaddingLeft();
        final int top = t + getPaddingTop();

        int validRight = r - getPaddingRight();

        int childLeft = left;
        int childTop = top;
        int maxHeightOnRow = 0;
        final int count = getChildCount();

        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child != null && child.getVisibility() != GONE) {
                int childWidth = child.getMeasuredWidth();
                int childHeight = child.getMeasuredHeight();
                MarginLayoutParams layoutParams = (MarginLayoutParams) child.getLayoutParams();

                int offsetHorizontal = spaceHorizontal + layoutParams.rightMargin;
                int offsetVertical = spaceVertical + layoutParams.bottomMargin;

                if (childLeft + childWidth + offsetHorizontal <= validRight) {
                    if (childHeight > maxHeightOnRow) {
                        maxHeightOnRow = childHeight;
                    }
                    childLeft += layoutParams.leftMargin;
                } else {
                    childLeft = left + layoutParams.leftMargin;
                    childTop += maxHeightOnRow + offsetVertical + layoutParams.topMargin;
                }

                int layoutLeft = childLeft;
                int layoutRight = layoutLeft + childWidth;
                int layoutTop = childTop;
                int layoutBottom = layoutTop + childHeight;

                child.layout(layoutLeft, layoutTop, layoutRight, layoutBottom);
                childLeft = layoutRight + offsetHorizontal;
            }
        }
    }

    private void layoutVertical(int l, int t, int r, int b) {
        final int left = l + getPaddingLeft();
        final int top = t + getPaddingTop();

        int validBottom = b - getPaddingBottom();

        int childLeft = left;
        int childTop = top;
        int maxWidthOnColumn = 0;
        final int count = getChildCount();

        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child != null && child.getVisibility() != GONE) {
                int childWidth = child.getMeasuredWidth();
                int childHeight = child.getMeasuredHeight();
                MarginLayoutParams layoutParams = (MarginLayoutParams) child.getLayoutParams();

                int offsetHorizontal = spaceHorizontal + layoutParams.rightMargin;
                int offsetVertical = spaceVertical + layoutParams.bottomMargin;

                if (childTop + childHeight + offsetVertical <= validBottom) {
                    if (childWidth > maxWidthOnColumn) {
                        maxWidthOnColumn = childWidth;
                    }
                    childTop += layoutParams.topMargin;
                } else {
                    childTop = top + layoutParams.topMargin;
                    childLeft += maxWidthOnColumn + offsetHorizontal + layoutParams.leftMargin;
                }

                int layoutLeft = childLeft;
                int layoutRight = layoutLeft + childWidth;
                int layoutTop = childTop;
                int layoutBottom = layoutTop + childHeight;

                child.layout(layoutLeft, layoutTop, layoutRight, layoutBottom);
                childTop = layoutBottom + offsetVertical;
            }
        }
    }

    /**
     * 清空非指定选项的check状态
     *
     * @param resId
     */
    private void clearCheckWithout(int resId) {
        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child != null && child instanceof RadioView) {
                int id = child.getId();
                RadioView radio = (RadioView) child;
                if (id == resId && !radio.isChecked()) {
                    radio.updateCheckStatus(true);
                    radio.updateCheck(true);
                }
                if (id != resId) {
                    radio.updateCheckStatus(false);
                    radio.updateCheck(false);
                }
            }
        }
    }

    private OnClickListener onRadioCheckListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            int id = v.getId();
            if (id == -1) {
                return;
            }
            if (v instanceof RadioView) {
                if (!((RadioView) v).isChecked()) {
                    ((RadioView) v).setCheck(true);
                    if (onCheckChangedListener != null) {
                        onCheckChangedListener.onCheckChanged(RadioBox.this, id);
                    }
                }
            }
        }
    };

    private RadioView.onRadioCheckChangedListener onRadioCheckChangedListener = (resId, checked) -> {
        if (resId == -1 || !checked) {
            return;
        }
        clearCheckWithout(resId);
    };

    public class CheckHierarchyChangeListener implements OnHierarchyChangeListener {

        @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
        @Override
        public void onChildViewAdded(View parent, View child) {
            if (parent == RadioBox.this && child instanceof RadioView) {
                int id = child.getId();
                // generates an id if it's missing
                if (id == View.NO_ID) {
                    id = View.generateViewId();
                    child.setId(id);
                }
                child.setOnClickListener(onRadioCheckListener);
                RadioView radioView = (RadioView) child;
                radioView.setOnRadioCheckChangedListener(onRadioCheckChangedListener);
                if (radioView.isChecked()) {
                    radioView.updateCheck(true);
                }
            }
        }

        @Override
        public void onChildViewRemoved(View parent, View child) {
            if (parent == RadioBox.this && child instanceof RadioView) {
                child.setOnClickListener(null);
                ((RadioView) child).setOnRadioCheckChangedListener(null);
            }
        }
    }

    public interface OnCheckChangedListener {
        void onCheckChanged(RadioBox group, int checkedId);
    }

    public void setSpaceHorizontal(int spaceHorizontal) {
        this.spaceHorizontal = spaceHorizontal;
    }

    public void setSpaceVertical(int spaceVertical) {
        this.spaceVertical = spaceVertical;
    }
}
